//
// Created by voyagerhui on 2022/3/18.
//

#ifndef CODECRAFT_2021_SOLVER_H
#define CODECRAFT_2021_SOLVER_H

#include "parameter.h"
#include "PSO.h"
#include "QuadProg++.hh"
#include <utility>

class PolicySolver{
public:
    vector<vector<int>> qos;
    map<string, vector<int>> demand;
    map<string, int> site_bandwidth;
    int qos_constraint;

    vector<string> T_name;  // 时刻序列
    vector<string> client_name;  // 客户节点名称
    vector<string> server_name;  // 边缘节点名称
    map<string, int> client_name2idx;  // 客户名称转qos列索引
    map<string, int> server_name2idx;  // 边缘节点名称转qos行索引

    map<string, int> site_rest;     // 节点剩余容量
    int T;  // 时刻数
    int R;  // 边缘节点个数
    int C;  // 客户节点个数

    vector<vector<vector<int>>> table;  // 每个时刻的答案表
    vector<string> ans;

    void greedy_policy();
    void init(vector<vector<int>> qos1, map<string, vector<int>> demand1,
                 map<string, int> site_bandwidth1, int qos_constraint1,
                 vector<string> T_name1, vector<string> client_name1,
                 vector<string> server_name1, map<string, int> client_name2idx1, map<string, int> server_name2idx1);
};


class PsoSolver{
public:
    int T;      // 时刻数
    int R;      // 边缘节点个数
    int C;      // 客户节点个数
    int idx_095;  // 0.95大成本的索引位置

    vector<vector<int>> qos;
    map<string, vector<int>> demand;
    map<string, int> site_bandwidth;
    int qos_constraint;

    vector<string> T_name;              // 时刻序列
    vector<string> client_name;         // 客户节点名称
    vector<string> server_name;         // 边缘节点名称
    vector<pair<int, int>> ban_cordinate;   // qos超出限制的table的坐标
    vector<bool> satisfied;             // 每个时刻是否满足

    vector<vector<vector<int>>> table;  // 每个时刻的表
    vector<int> table1d;                // table的1维形式
    vector<vector<int>> col_sum;        // 当前时刻列和
    vector<vector<int>> row_sum;        // 当前时刻行和

    // init
    void init(vector<vector<int>> qos1, map<string, vector<int>> demand1,
              map<string, int> site_bandwidth1, int qos_constraint1, vector<string> T_name1,
              vector<string> client_name1, vector<string> server_name1,
              vector<vector<vector<int>>> inital_table);
    // 3维矩阵转1维矩阵
    void table2table1d();
    // 1维矩阵转3维矩阵
    void table1d2table();
    // 计算不能提供服务的表格坐标
    void cal_ban_ordinate();
    // 计算时刻t的列和
    void cal_col_sum(int t);
    // 计算时刻t的行和
    void cal_row_sum(int t);
    // 对table的t时刻按比例调整满足有效性
    void adjust_table(int t);
    // 时刻t是否被满足
    bool is_time_t_satisfied(int t);
    // 检查每个时刻客户都被满足了
    bool is_all_satisfied();
    // 边缘节点idx都流量序列
    vector<int> get_server_flow_seq(int idx);
    // 边缘节点idx的成本
    int get_server_cost(int idx);
    // 检查行列约束是否满足，打印不满足约束的行数和列数
    void check_constrains_break();
    // 打印最终的table表
    void write_final_table();
    // 返回成本
    long long get_cost();
    // 返回结果
    vector<string> get_answer();
    // PSO 算法
    void pso_optimize();
    // 二维矩阵转一维矩阵
    vector<int> matrix2vector(vector<vector<int>> a);
    // 二次规划 算法
    void qp_optimize();
};

extern class PsoSolver pso_solver;

#endif //CODECRAFT_2021_SOLVER_H
